package com.neusoft.ch4;

import java.util.Arrays;

/*
 * 课堂笔记：
 *    1、二维数组：
 *       二维数组可以表示行和列。
 *    二维数组的声明定义：
 *       声明定义：
 *    声明语法：
 *        数据类型[][]  变量名; // java推荐
 *        变量名= 初始值;
 *        
 *        或者：
 *        数据类型  变量名[][]; // c语言习惯
 *        
 *        
 *    初始化：
 *        申请内存：
 *           变量名 = new 数据类型[数组的行数][数组的列数];
 *           
 *           或者： 
 *           变量名 = new 数据类型[数组的行数][]; // 声明定义行数
 *           变量名[行下标] = new int[列数]; // 声明定义列数
 *           变量名[行下标] = new int[]{值0,值1,值N}; // 声明定义列数 *           
 *           注意：
 *              该种声明方式相当于是行和列分别进行了声明定义；
 *        申请内存并赋值：
 *           变量名 = new 数据类型[][]{{0行0列,0行1列,0行n列},{1行0列,1行1列,1行n列},{2行0列,2行1列,2行n列}};  
 *           注意：[]中不需要写数组长度，数据的长度由{}中元素的个数决定；
 *        声明并赋值：
 *           数据类型[]  变量名 = {{0行0列,0行1列,0行n列},{1行0列,1行1列,1行n列},{2行0列,2行1列,2行n列}};
 *           注意：这种方式声明和赋值不能分开写；       
 *     
 *    解析：
 *        二维数组表示的是行和列；
 *        一个元素有两个下标：一个是行下标、一个是列下标；（前面是行标，后面是列标）
 *        在二维数组中，数组变量名.length表示的是二维数组的行数；
 *                  数组变量名[行标].length表示的是当前行的列数； 
 *        在二维数组中，行的维度是必须要给定；
 *        二维数组在内存中还是连续存储的；不规则的二维数组在内存中也是连续存储的；
 *        二维数组的数组名是数组在内存中的入口地址；
 *        数组名[行标]是数组中的改行的入口地址；
 *   
 *   2、数组的扩容和相关的工具类方法（了解会用即可）
 *      数组的扩容：
 *         因为数组一旦申请完内存以后，其大小就固定不能改变；那么，数组容量不足时，如何进行扩展？
 *         数组扩容步骤：
 *            (1)重新声明定义一个更大容量的新的数组；
 *            (2)将旧的数组的内容复制到新的数组中；
 *            (3)将原数组的名字指向新数组。 
 *      
 *      Arrays工具类的sort方法默认只能对基本类型排序：
 *          整型 、浮点数从小到大排序；
 *          字符串默认按字典顺序排序；         
 *               
 */
public class TestCh4 {

	public static void main(String[] args) {
		test03();
	}
	
	/**
	 * 数组使用Arrays工具类中的sort方法进行排序
	 */
	private static void test03() {
		// 声明一个数组
		int[] arr = new int[] {10,2,13,4,5};
		// 打印旧数组
		System.out.println("排序前数组内容：");
		for(int i=0;i<arr.length;i++) {
			System.out.print(" "+arr[i]);
		}
		System.out.println();
		// 调用Arrays工具类进行排序
		Arrays.sort(arr);
		// 打印排序之后的内容
		System.out.println("排序后数组内容：");
		for(int i=arr.length-1;i>=0;i--) {
			System.out.print(" "+arr[i]);
		}
		System.out.println();
	}
	/**
	 * 数组扩容
	 */
	private static void test022() {
		// 声明一个数组
		int[] arr = new int[] {1,2,3,4,5};
		// 打印旧数组
		System.out.println("旧数组内容：");
		for(int i=0;i<arr.length;i++) {
			System.out.print(" "+arr[i]);
		}
		System.out.println();
		// 将数组arr的容量扩充一倍
		//(1)重新声明定义一个更大容量的新的数组；
		int[] arrNew = new int[arr.length*2];
		//(2)将旧的数组的内容复制到新的数组中；
//		for(int i=0;i<arr.length;i++) {
//			// 复制:旧数组的内容复制到新数组中
//			arrNew[i] = arr[i];
//		}
		System.arraycopy(arr, 0, arrNew, 0, arr.length);
		// (3)将原数组的名字指向新数组。   
		arr = arrNew;
		
		// 打印旧数组
		System.out.println("新数组内容：");
		for (int i = 0; i < arr.length; i++) {
			System.out.print(" " + arr[i]);
		}
		System.out.println();
	}
	/**
	 * 数组扩容
	 */
	private static void test021() {
		// 声明一个数组
		int[] arr = new int[] {1,2,3,4,5};
		// 打印旧数组
		System.out.println("旧数组内容：");
		for(int i=0;i<arr.length;i++) {
			System.out.print(" "+arr[i]);
		}
		System.out.println();
		// 将数组arr的容量扩充一倍
		//(1)重新声明定义一个更大容量的新的数组；
		//int[] arrNew = new int[arr.length*2];
		//(2)将旧的数组的内容复制到新的数组中；
//		for(int i=0;i<arr.length;i++) {
//			// 复制:旧数组的内容复制到新数组中
//			arrNew[i] = arr[i];
//		}
		int[] arrNew = Arrays.copyOf(arr, arr.length*2);
		// (3)将原数组的名字指向新数组。   
		arr = arrNew;
		
		// 打印旧数组
		System.out.println("新数组内容：");
		for (int i = 0; i < arr.length; i++) {
			System.out.print(" " + arr[i]);
		}
		System.out.println();
	}
	
	/**
	 * 数组扩容
	 */
	private static void test02() {
		// 声明一个数组
		int[] arr = new int[] {1,2,3,4,5};
		// 打印旧数组
		System.out.println("旧数组内容：");
		for(int i=0;i<arr.length;i++) {
			System.out.print(" "+arr[i]);
		}
		System.out.println();
		// 将数组arr的容量扩充一倍
		//(1)重新声明定义一个更大容量的新的数组；
		int[] arrNew = new int[arr.length*2];
		//(2)将旧的数组的内容复制到新的数组中；
		for(int i=0;i<arr.length;i++) {
			// 复制:旧数组的内容复制到新数组中
			arrNew[i] = arr[i];
		}
		// (3)将原数组的名字指向新数组。   
		arr = arrNew;
		
		// 打印旧数组
		System.out.println("新数组内容：");
		for (int i = 0; i < arr.length; i++) {
			System.out.print(" " + arr[i]);
		}
		System.out.println();
	}
	
	
	
	
	
	/**
	 * 二维数组的声明定义
	 */
	private static void test01() {
		// 声明
		int[][] arr01;
		// 分配内存
		arr01 = new int[3][3];
		// 声明
		int[][] arr02;
		arr02 = new int[][] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
		// 声明初始化
		int[][] arr03 = { { 7, 8, 9 }, { 4, 5, 6, 6 }, { 1, 2, 3 } };
		// 声明
		int[][] arr04;
		arr04 = new int[3][];
		// 可以先定义行数
		// 每行有多少列，则需要通过逐行进行初始化定义，对于行的定义声明其实就是一维数组
		// 二维数组的一行就是一个一维数组
		arr04[0] = new int[3];
		arr04[1] = new int[] { 2, 3, 4 };
		arr04[2] = new int[] { 5, 6, 7 };

		// 使用双层嵌套循环遍历二维数组
		// 遍历二维数组的行数
		// arr04.length表示数组arr04的行数
		for (int i = 0; i < arr03.length; i++) {
			// 遍历列
			// arr04[i].length表示arr04二维数组行标为i的这一行的列数
			for (int j = 0; j < arr03[i].length; j++) {
				System.out.print("  " + arr03[i][j]);
			}
			// 换行
			System.out.println();
		}

	}

}
